home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / ICProgKit1.0 / Source / RandomSignature / ICRandomSignature.p next >
Text File  |  1994-11-27  |  14KB  |  498 lines

  1. unit ICRandomSignature;
  2.  
  3. interface
  4.  
  5.     uses
  6.         Components;
  7.  
  8.     function Main (var params: ComponentParameters; storage: Handle): ComponentResult;
  9.  
  10. implementation
  11.  
  12.     uses
  13. {$ifc undefined THINK_Pascal}
  14.         Types, Files, QuickDraw, Aliases, Packages, Memory, Errors, ToolUtils, Resources, 
  15.  
  16.         ICTypes, 
  17. {$endc}
  18.         Folders, ICCAPI, ICKeys;
  19.  
  20.     const
  21.         kOurComponentManufacturer = 'JMJ ';
  22.  
  23.     function DecStr (l: longint): Str32;
  24.         var
  25.             tmpstr: Str255;
  26.     begin
  27.         NumToString(l, tmpstr);
  28.         DecStr := tmpstr;
  29.     end; (* DecStr *)
  30.  
  31.     const
  32.         kICCStart = 0;
  33.         kICCStop = 1;
  34.         kICCFindConfigFile = 2;
  35.         kICCSpecifyConfigFile = 3;
  36.         kICCGetSeed = 4;
  37.         kICCBegin = 5;
  38.         kICCGetPref = 6;
  39.         kICCSetPref = 7;
  40.         kICCCountPref = 8;
  41.         kICCGetIndPref = 9;
  42.         kICCEnd = 10;
  43.         kICCDefaultFile = 11;
  44.         kICCDeletePref = 12;
  45.         kICCGetPerm = 13;
  46.  
  47.         kICC_first_select = kICCStart;
  48.         kICC_last_select = kICCGetPerm;
  49.  
  50.     type
  51.         globalsRecord = record
  52.                 self: ComponentInstance;
  53.                 target: ComponentInstance;
  54.                 delegate: ComponentInstance;
  55.  
  56.                 current_signature: Handle;
  57.                 default_signature: Handle;
  58.                 sig_folder_name: Str63;
  59.             end;
  60.         globalsPtr = ^globalsRecord;
  61.         globalsHandle = ^globalsPtr;
  62.  
  63.         sharedGlobals = record
  64.                 delegate: Component;
  65.             end;
  66.         sharedGlobalsPtr = ^sharedGlobals;
  67.  
  68.     function GetSharedGlobals (globals: globalsHandle): sharedGlobalsPtr;
  69.         var
  70.             shared: sharedGlobalsPtr;
  71.     begin
  72.         shared := nil;
  73.         if GetComponentInstanceA5(globals^^.self) = 0 then begin
  74.             shared := sharedGlobalsPtr(GetComponentRefcon(Component(globals^^.self)));
  75.         end
  76.         else begin
  77. (* Debugger; *)
  78. (* This, needless to say, is not the correct answer.  You're support to go madly search for the component. *)
  79. (* I just can't be bothered to deal with this at the moment. *)
  80.         end; (* if *)
  81.         GetSharedGlobals := shared;
  82.     end; (* GetSharedGlobals *)
  83.  
  84. (* Component Manager routines *)
  85.  
  86.     function RSCRegister (globals: globalsHandle): ComponentResult;
  87.         var
  88.             shared: sharedGlobalsPtr;
  89.             err: OSErr;
  90.             junk: OSErr;
  91.     begin
  92.         junk := SetDefaultComponent(Component(globals^^.self), defaultComponentIdentical + defaultComponentAnyFlags);
  93.         shared := sharedGlobalsPtr(NewPtrSysClear(sizeof(sharedGlobals)));
  94.         err := MemError;
  95.         if err = noErr then begin
  96.             shared^.delegate := nil;
  97.             SetComponentRefcon(Component(globals^^.self), longint(shared));
  98.         end; (* if *)
  99.         RSCRegister := err;
  100.     end; (* RSCRegister *)
  101.  
  102.     function RSCUnregister (globals: globalsHandle): ComponentResult;
  103.         var
  104.             shared: sharedGlobalsPtr;
  105.             result: ComponentResult;
  106.     begin
  107.         result := -1;
  108.         shared := GetSharedGlobals(globals);
  109.         if shared <> nil then begin
  110.             result := UncaptureComponent(shared^.delegate);
  111.             DisposePtr(Ptr(shared));
  112.         end; (* if *)
  113.         RSCUnregister := result;
  114.     end; (* RSCUnregister *)
  115.  
  116.     function RSCCanDo (globals: globalsHandle; selector: integer): ComponentResult;
  117.     (* Handle the Component Manager CanDo request.*)
  118.     begin
  119.         case selector of
  120.             kComponentUnregisterSelect..kComponentOpenSelect: 
  121.                 RSCCanDo := 1;
  122.             otherwise
  123.                 RSCCanDo := ComponentFunctionImplemented(globals^^.delegate, selector);
  124.         end; (* case *)
  125.     end; (* RSCCanDo *)
  126.  
  127.     function FindDelegate (after: Component): Component;
  128.         var
  129.             cd: ComponentDescription;
  130.             found_cd: ComponentDescription;
  131.             current: Component;
  132.             found: boolean;
  133.     begin
  134.         cd.componentType := internetConfigurationComponentType;
  135.         cd.componentSubType := internetConfigurationComponentSubType;
  136.         cd.componentManufacturer := OSType(0);
  137.         cd.componentFlags := 0;
  138.         cd.componentFlagsMask := 0;
  139.         current := after;
  140.         repeat
  141.             (* DebugStr(concat('in loop for ', kOurComponentManufacturer)); *)
  142.             current := FindNextComponent(current, cd);
  143.             if current <> nil then begin
  144.                 if GetComponentInfo(current, found_cd, nil, nil, nil) = noErr then begin
  145.                     found := (found_cd.componentManufacturer <> kOurComponentManufacturer);
  146.                 end; (* if *)
  147.             end; (* if *)
  148.         until found or (current = nil);
  149.         FindDelegate := current;
  150.     end; (* FindDelegate *)
  151.  
  152.     function InitGlobals (globals: globalsHandle): ComponentResult;
  153.         var
  154.             err: ComponentResult;
  155.             refnum: integer;
  156.             strh: StringHandle;
  157.             junk: OSErr;
  158.     begin
  159.         err := noErr;
  160.         refnum := OpenComponentResFile(Component(globals^^.self));
  161.         if refnum <= 0 then begin
  162.             err := resNotFound;
  163.         end; (* if *)
  164.         if err = noErr then begin
  165.             strh := GetString(130);
  166.             if strh = nil then begin
  167.                 err := resNotFound;
  168.             end
  169.             else begin
  170.                 globals^^.sig_folder_name := strh^^;
  171.             end; (* if *)
  172.             if err = noErr then begin
  173.                 globals^^.default_signature := Get1Resource('TEXT', 128);
  174.                 if globals^^.default_signature = nil then begin
  175.                     err := resNotFound;
  176.                 end
  177.                 else begin
  178.                     DetachResource(globals^^.default_signature);
  179.                 end; (* if *)
  180.                 globals^^.current_signature := nil;
  181.             end; (* if *)
  182.             junk := CloseComponentResFile(refnum);
  183.         end; (* if *)
  184.         InitGlobals := err;
  185.     end; (* InitGlobals *)
  186.  
  187.     function RSCOpen (globals: globalsHandle; self: ComponentInstance): ComponentResult;
  188.     (* Handle the Component Manager Open request, mostly delayed until ICCStart. *)
  189.         var
  190.             err: ComponentResult;
  191.             cap: Component;
  192.             shared: sharedGlobalsPtr;
  193.             tmp: Component;
  194.     begin
  195.         (* create our globals *)
  196.         globals := globalsHandle(NewHandleClear(sizeof(globalsRecord)));
  197.         err := MemError;
  198.         if err = noErr then begin
  199.             HLock(Handle(globals));
  200. (* Debugger; *)
  201.             globals^^.self := self;
  202.             SetComponentInstanceStorage(self, Handle(globals));
  203.             shared := GetSharedGlobals(globals);
  204.             if shared <> nil then begin
  205.                 if shared^.delegate = nil then begin
  206.                     tmp := FindDelegate(Component(self));
  207.                     if tmp <> nil then begin
  208.                         shared^.delegate := CaptureComponent(tmp, Component(self));
  209.                     end; (* if *)
  210.                 end; (* if *)
  211.                 globals^^.delegate := OpenComponent(shared^.delegate);
  212.                 err := ComponentSetTarget(self, self);
  213.             end; (* if *)
  214.             if err = noErr then begin
  215.                 err := InitGlobals(globals);
  216.             end; (* if *)
  217.             HUnlock(Handle(globals));
  218.         end; (* if *)
  219.         RSCOpen := err;
  220.     end; (* RSCOpen *)
  221.  
  222.     function RSCClose (globals: globalsHandle; self: ComponentInstance): ComponentResult;
  223.     (* Handle the Component Manager Close request. *)
  224.         var
  225.             err: ComponentResult;
  226.             junk: OSErr;
  227.     begin
  228.         err := noErr;
  229.         if globals <> nil then begin
  230.             if globals^^.delegate <> nil then begin
  231.                 junk := CloseComponent(globals^^.delegate)
  232.             end; (* if *)
  233.             DisposeHandle(Handle(globals));
  234.         end; (* if *)
  235.         RSCClose := err;
  236.     end; (* RSCClose *)
  237.  
  238.     function RSCTarget (globals: globalsHandle; new_target: ComponentInstance): ComponentResult;
  239.     (* Handle the Component Manager Target. *)
  240.         var
  241.             err: ComponentResult;
  242.     begin
  243.         globals^^.target := new_target;
  244.         if globals^^.delegate <> nil then begin
  245.             err := ComponentSetTarget(globals^^.delegate, new_target);
  246.         end
  247.         else begin
  248.             err := noErr;
  249.         end; (* if *)
  250.         RSCTarget := err;
  251.     end; (* RSCTarget *)
  252.  
  253. (* Internet Configuration specific routines *)
  254.  
  255.     function GetRandomSignature (globals: globalsHandle): Handle;
  256.         var
  257.             cpb: CInfoPBRec;
  258.             sig: FSSpec;
  259.  
  260.         function GetNthTextFile (max_count: integer; var count: integer): OSErr;
  261.             var
  262.                 err: OSErr;
  263.                 index: integer;
  264.         begin
  265.             count := 0;
  266.             index := 1;
  267.             repeat
  268.                 cpb.ioNamePtr := @sig.name;
  269.                 cpb.ioDirID := sig.parID;
  270.                 cpb.ioVRefNum := sig.vRefNum;
  271.                 cpb.ioFDirIndex := index;
  272.                 err := PBGetCatInfoSync(@cpb);
  273.                 index := index + 1;
  274.                 if (err = noErr) and not btst(cpb.ioFlAttrib, 4) and (cpb.ioFlFndrInfo.fdType = 'TEXT') then begin
  275.                     count := count + 1;
  276.                 end; (* if *)
  277.             until (err <> noErr) or (count = max_count);
  278.             GetNthTextFile := err;
  279.         end; (* GetNthTextFile *)
  280.  
  281.         var
  282.             junk: OSErr;
  283.             texth: Handle;
  284.             err: OSErr;
  285.             ref: integer;
  286.             count: integer;
  287.             length: longint;
  288.     begin
  289.         texth := nil;
  290.         sig.name := globals^^.sig_folder_name;
  291.         err := FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, sig.vRefNum, sig.parID);
  292.         if err = noErr then begin
  293.             cpb.ioNamePtr := @sig.name;
  294.             cpb.ioVRefNum := sig.vRefNum;
  295.             cpb.ioDirID := sig.parID;
  296.             cpb.ioFDirIndex := 0;
  297.             err := PBGetCatInfoSync(@cpb);
  298.         end; (* if *)
  299.         if (err = noErr) and not btst(cpb.ioFlAttrib, 4) then begin
  300.             err := dirNFErr;
  301.         end; (* if *)
  302.         if err = noErr then begin
  303.             sig.parID := cpb.ioDirID;
  304.             junk := GetNthTextFile(32767, count);
  305.             if count = 0 then begin
  306.                 err := fnfErr;
  307.             end
  308.             else begin
  309.                 count := (abs(random) mod count) + 1;
  310.                 err := GetNthTextFile(count, junk);
  311.             end; (* if *)
  312.         end; (* if *)
  313.         if err = noErr then begin
  314.             err := HOpen(sig.vRefNum, sig.parID, sig.name, fsRdPerm, ref);
  315.         end; (* if *)
  316.         if err = noErr then begin
  317.             err := GetEOF(ref, length);
  318.             if err = noErr then begin
  319.                 if length > 4096 then begin
  320.                     length := 4096;
  321.                 end; (* if *)
  322.                 texth := NewHandle(length);
  323.                 err := MemError;
  324.             end; (* if *)
  325.             if err = noErr then begin
  326.                 err := FSRead(ref, length, texth^);
  327.             end; (* if *)
  328.             junk := FSClose(ref);
  329.         end; (* if *)
  330.         if err <> noErr then begin
  331.             DisposeHandle(texth);
  332.             texth := nil;
  333.         end; (* if *)
  334.         if texth = nil then begin
  335.             texth := globals^^.default_signature;
  336.             err := HandToHand(texth);
  337.             if err <> noErr then begin
  338.                 texth := nil;
  339.             end; (* if *)
  340.         end; (* if *)
  341.         GetRandomSignature := texth;
  342.     end; (* GetRandomSignature *)
  343.  
  344.     procedure ChooseRandomSignature (globals: globalsHandle);
  345.     begin
  346.         if globals^^.current_signature <> nil then begin
  347.             DisposeHandle(globals^^.current_signature);
  348.         end; (* if *)
  349.         globals^^.current_signature := GetRandomSignature(globals);
  350.     end; (* ChooseRandomSignature *)
  351.  
  352.     const
  353.         delegateThisCallErr = 1;
  354.  
  355.     function RSCBegin (globals: globalsHandle; perm: ICPerm): ICError;
  356.         var
  357.             err: ICError;
  358.     begin
  359.         ChooseRandomSignature(globals);
  360.         RSCBegin := delegateThisCallErr;
  361.     end; (* RSCBegin *)
  362.  
  363.     function RSCGetPref (globals: globalsHandle; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
  364.         var
  365.             tmpstr: Str255;
  366.             perm: icPerm;
  367.             max_size: longint;
  368.             err: ICError;
  369.     begin
  370.         if IUEqualString(key, kICSignature) = 0 then begin
  371.             if (ICCGetPerm(globals^^.delegate, perm) = noErr) & (perm = icNoPerm) then begin
  372.                 ChooseRandomSignature(globals);
  373.             end; (* if *)
  374.  
  375.             max_size := size;
  376.             if globals^^.current_signature = nil then begin
  377.                 size := 0;
  378.             end
  379.             else begin
  380.                 size := GetHandleSize(globals^^.current_signature);
  381.             end; (* if *)
  382.  
  383.             err := noErr;
  384.             if ((max_size < 0) and (buf <> nil)) then begin
  385.                 err := paramErr;
  386.             end; (* if *)
  387.             if (err = noErr) and (buf <> nil) then begin
  388.                 if size > max_size then begin
  389.                     err := icTruncatedErr;
  390.                 end
  391.                 else begin
  392.                     max_size := size;
  393.                 end; (* if *)
  394.                 if max_size <> 0 then begin
  395.                     BlockMove(globals^^.current_signature^, buf, max_size);
  396.                 end; (* if *)
  397.             end; (* if *)
  398.  
  399.             attr := ICattr_locked_mask + ICattr_volatile_mask;
  400.             RSCGetPref := err;
  401.         end
  402.         else begin
  403.             RSCGetPref := delegateThisCallErr;
  404.         end; (* if *)
  405.     end; (* RSCGetPref *)
  406.  
  407.     function RSCSetPref (globals: globalsHandle; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
  408.     begin
  409.         if IUEqualString(key, kICSignature) = 0 then begin
  410.             RSCSetPref := icPermErr;
  411.         end
  412.         else begin
  413.             RSCSetPref := delegateThisCallErr;
  414.         end; (* if *)
  415.     end; (* RSCSetPref *)
  416.  
  417.     function WhatToStr (what: integer): Str32;
  418.     begin
  419.         case what of
  420.             (* Component Manager stuff *)
  421.             kComponentVersionSelect: 
  422.                 WhatToStr := 'kComponentVersionSelect';
  423.             kComponentCanDoSelect: 
  424.                 WhatToStr := 'kComponentCanDoSelect';
  425.             kComponentOpenSelect: 
  426.                 WhatToStr := 'kComponentOpenSelect';
  427.             kComponentCloseSelect: 
  428.                 WhatToStr := 'kComponentCloseSelect';
  429.             kComponentTargetSelect: 
  430.                 WhatToStr := 'kComponentTargetSelect';
  431.             kComponentRegisterSelect: 
  432.                 WhatToStr := 'kComponentRegisterSelect';
  433.             kComponentUnregisterSelect: 
  434.                 WhatToStr := 'kComponentUnregisterSelect';
  435.             (* this component type stuff *)
  436.             kICCGetPref: 
  437.                 WhatToStr := 'kICCGetPref';
  438.             kICCSetPref: 
  439.                 WhatToStr := 'kICCSetPref';
  440.             otherwise
  441.                 WhatToStr := 'other';
  442.         end; (* case *)
  443.     end; (* WhatToStr *)
  444.  
  445.     function Main (var params: ComponentParameters; storage: Handle): ComponentResult;
  446.     (* Component entry point.  It's pretty neat IMHO. *)
  447.         var
  448.             proc: ProcPtr;
  449.             s: signedByte;
  450.             res: longint;
  451.     begin
  452.         proc := nil;
  453. (* DebugStr(concat('Enter ', WhatToStr(params.what))); *)
  454.         case params.what of
  455.             (* Component Manager stuff *)
  456.             kComponentVersionSelect: 
  457.                 Main := internetConfigurationComponentInterfaceVersion;
  458.             kComponentCanDoSelect: 
  459.                 proc := @RSCCanDo;
  460.             kComponentOpenSelect: 
  461.                 proc := @RSCOpen;
  462.             kComponentCloseSelect: 
  463.                 proc := @RSCClose;
  464.             kComponentTargetSelect: 
  465.                 proc := @RSCTarget;
  466.             kComponentRegisterSelect: 
  467.                 proc := @RSCRegister;
  468.             kComponentUnregisterSelect: 
  469.                 proc := @RSCUnregister;
  470.             (* this component type stuff *)
  471.             kICCBegin: 
  472.                 proc := @RSCBegin;
  473.             kICCGetPref: 
  474.                 proc := @RSCGetPref;
  475.             kICCSetPref: 
  476.                 proc := @RSCSetPref;
  477.             otherwise
  478.                 ;
  479.         end; (* case *)
  480.         if storage <> nil then begin
  481.             s := HGetState(storage);
  482.             HLock(storage);
  483.         end; (* if *)
  484.         res := delegateThisCallErr;
  485.         if proc <> nil then begin
  486.             res := CallComponentFunctionWithStorage(storage, params, proc);
  487.         end; (* if *)
  488.         if res = delegateThisCallErr then begin
  489.             res := DelegateComponentCall(params, globalsHandle(storage)^^.delegate);
  490.         end; (* if *)
  491. (* DebugStr(concat('Exit ', WhatToStr(params.what), ' with res ', DecStr(res))); *)
  492.         Main := res;
  493.         if storage <> nil then begin
  494.             HSetState(storage, s);
  495.         end; (* if *)
  496.     end; (* Main *)
  497.  
  498. end. (* ICRandomSignature *)